<template>
    <div class="textarea-wrapper">
        <!--前置插槽-->
        <div v-if="hasPrefix" class="prefix-slot">
            <slot name="prefix"></slot>
        </div>
        <!--主体textarea-->
        <textarea ref="textareaRef"
            :value="modelValue"
            @input="handleInput"
            :style="textareaStyle"
            :placeholder="placeholder"
        ></textarea>
        <!--后置插槽-->
        <div v-if="hasSuffix" class="suffix-slot">
            <slot name="suffix"></slot>
        </div>
        
    </div>
</template>
<script lang="ts" setup name="autoSizeTextArea">
import { debounce } from 'lodash';
import { CSSProperties } from 'vue';
    /**父传子变量定义*/    
    const props=defineProps({
        modelValue:{
            type:String,
            default:''
        },
        placeholder:{
            type:String,
            default:''
        },
        minHeight:{
            type:Number,
            default:50
        },
        maxHeight:{
            type:Number,
            default:400
        },
        debounceTime:{
            type:Number,
            default:200
        }
    });
    //插槽获取
    defineSlots<{
        prefix?: (props: {}) => any
        suffix?: (props: {}) => any
    }>();
    //插槽
    const slots=useSlots();
    //安全调用
    const hasPrefix = computed(() => !!slots.prefix); 
    const hasSuffix = computed(() => !!slots.suffix);

    //发送父组件
    const emit=defineEmits(['update:modelValue']);
    //样式
    const textareaStyle = computed<CSSProperties>(() => {
        return {
            minHeight: `${props.minHeight}px`,
            maxHeight: `${props.maxHeight}px`,
            overflowY: 'hidden'
        };
    });
    //重算大小
    const textareaRef=ref<HTMLTextAreaElement | null>(null);
    const resizeTextarea=()=>{
        if(!textareaRef.value){
            return;
        }
        textareaRef.value.style.height='auto';
        const height=Math.min(textareaRef.value.scrollHeight,props.maxHeight);
        textareaRef.value.style.height=`${height}px`;
        textareaRef.value.style.overflowY=height>=props.maxHeight?'auto':'hidden';
    }
    //防抖
    const debouncedResize=debounce(resizeTextarea,props.debounceTime);
    //输入监听
    const handleInput=(e: Event)=>{
        const target=e.target as HTMLTextAreaElement;
        emit('update:modelValue',target.value);
        debouncedResize();
    }
    //初始化加载
    onMounted(()=>{
        resizeTextarea();
    });
    //监视函数
    watch(()=>props.modelValue,()=>{
        debouncedResize();
    });
</script>
<style scoped>
    .textarea-wrapper{
        display: flex;
        border: 2px solid #ccc;/**添加边框*/
        align-items: flex-end;/* 确保按钮垂直居中 */
        width: 100%;
    }
    /*textarea 样式赋值*/
    textarea{
        flex-grow: 1; /* 让 textarea 占据剩余空间 */
        margin-right: 10px; /* 为按钮留出空间 */
        overflow-y: hidden;/*隐藏滚动条*/
        resize: none;/*取消小三角*/ 
        transition: height 0.2 ease;/**动画特效*/
        line-height: 1.5;   
    }
    .prefix-slot, .suffix-slot {
        display: flex;
        align-items: center;
        color: #909399;
    }

    .prefix-slot {
        margin-right: 8px;
    }

    .suffix-slot {
        margin-left: 8px;
    }

</style>